package jp.sinmetal.trainer.service;


import jp.sinmetal.trainer.entity.Member;
import jp.sinmetal.trainer.exception.AuthenticationException;
import jp.sinmetal.trainer.util.DateUtil;
import jp.sinmetal.trainer.util.HashGeneratorUtil;

/**
 * メンバーサービス
 * @author sin
 *
 */
public class MemberService extends AbstractService<Member> {

    /**
     * メンバーIDを基にエンティティを返す
     * @author sin
     *
     * @param memberId
     * @return
     */
    public Member findById(Integer memberId) {
        return select().id(memberId).getSingleResult();
    }

    /**
     * twitterIDを基にエンティティを返す
     * @author sin
     *
     * @param twitterId
     * @return
     */
    public Member findByTwitterId(Integer twitterId) {
    	return select().where(SW().eq("twitterId", twitterId)).getSingleResult();
    }

    /**
     * 認証
     * @author sin
     *
     * @param loginId
     * @param password
     * @return 成功：メンバーエンティティ,失敗：NULL
     * @throws AuthenticationException
     */
    public Member authtication(Member entity) throws AuthenticationException {
    	Member member = select()
    						.where(SW()
    								.eq("loginId", entity.loginId)
    								.eq("password", HashGeneratorUtil.getHash(entity.password))
    								.eq("deleteFlag", false))
    						.getSingleResult();

    	if (member != null) {
    		return member;
    	} else {
    		throw new AuthenticationException(AuthenticationException.AUTHENTICATION_ERROR);
    	}
    }

    /**
     * メンバー作成
     * @author sin
     *
     * @param entity
     * @return
     */
    public int insertMember(Member entity) {
    	entity.deleteFlag = false;
    	entity.entryDate = DateUtil.getNow();

    	return jdbcManager.insert(entity).execute();
    }

    /**
     * 変更があった項目のみ、更新
     * @author sin
     *
     * @param entity
     * @param before
     * @return
     */
    public int updateMemberChangedFrom(Member entity, Member before) {
    	return jdbcManager.update(entity).changedFrom(before).execute();
    }

    /**
     * メンバー更新
     * @author sin
     *
     * @param entity
     * @return
     */
    public int updateMember(Member entity) {
    	return jdbcManager.update(entity).includes("friendCode","communicationTime").includesVersion().execute();
    }

    /**
     * メンバー削除
     * @author sin
     *
     * @param memberId
     * @return
     */
    public int deleteMember(Member entity) {
    	entity.deleteFlag = true;

    	return jdbcManager.update(entity).includes("delete_flag").execute();
    }
}